package top.tangyh.lamp.care.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.pagehelper.util.StringUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.tangyh.basic.context.ContextUtil;
import top.tangyh.basic.database.mybatis.conditions.Wraps;
import top.tangyh.basic.database.mybatis.conditions.query.LbQueryWrap;
import top.tangyh.basic.exception.BizException;
import top.tangyh.lamp.care.entity.BPgRecordDetail;
import top.tangyh.lamp.care.entity.BPgpf;
import top.tangyh.lamp.care.entity.BPipeUseRecord;
import top.tangyh.lamp.care.mapper.BPgRecordDetailMapper;
import top.tangyh.lamp.care.mapper.BPgRecordMapper;
import top.tangyh.lamp.care.mapper.BPgpfMapper;
import top.tangyh.lamp.care.service.BPgRecordDetailService;
import top.tangyh.lamp.care.service.BPgRecordService;
import top.tangyh.basic.base.service.impl.SuperServiceImpl;
import top.tangyh.lamp.care.manager.BPgRecordManager;
import top.tangyh.lamp.care.entity.BPgRecord;
import top.tangyh.lamp.care.service.BPgpfService;
import top.tangyh.lamp.care.vo.query.PgRecordInVO;
import top.tangyh.lamp.care.vo.query.PgRecordQueryVo;
import top.tangyh.lamp.care.vo.query.QcQueryPageVO;
import top.tangyh.lamp.care.vo.result.*;
import top.tangyh.lamp.care.vo.save.BPgRecordSaveVO;
import top.tangyh.lamp.care.vo.save.PgRecordDetailVo;
import top.tangyh.lamp.care.vo.save.PgRecordVo;
import top.tangyh.lamp.care.vo.update.BPgRecordUpdateVO;
import top.tangyh.lamp.care.vo.query.BPgRecordPageQuery;
import top.tangyh.lamp.common.constant.ModelItemConstant;
import top.tangyh.lamp.common.utils.ConvertUtil;
import top.tangyh.lamp.common.utils.PDateUtils;

import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;


/**
 * <p>
 * 业务实现类
 * 评估评分
 * </p>
 *
 * @author zqb
 * @date 2024-07-09 08:35:22
 * @create [2024-07-09 08:35:22] [zqb]
 */
@Slf4j
@RequiredArgsConstructor
@Service
@Transactional(readOnly = true)
public class BPgRecordServiceImpl extends SuperServiceImpl<BPgRecordManager, Long, BPgRecord> implements BPgRecordService {

    private final BPgRecordMapper bPgRecordMapper;


    private final BPgRecordDetailMapper bPgRecordDetailMapper;

    private final BPgpfService bPgpfService;

    private final BPgRecordDetailService bPgRecordDetailService;


    private final BPgpfMapper bPgpfMapper;

    @Override
    public List<BPgRecordResultVO> selectByPid(PgRecordQueryVo pgRecordQueryVo) {

        LbQueryWrap<BPgRecord> wrap = Wraps.<BPgRecord>lbQ();
        if (null != pgRecordQueryVo.getRkTime()) {
            wrap.ge(BPgRecord::getGradeTime, pgRecordQueryVo.getRkTime());
        }
        if (null != pgRecordQueryVo.getCkTime()) {
            wrap.le(BPgRecord::getGradeTime, new Date(pgRecordQueryVo.getCkTime()));
        }
        if (null != pgRecordQueryVo.getPgId()) {
            wrap.eq(BPgRecord::getPgId, pgRecordQueryVo.getPgId());
        }
        if (null != pgRecordQueryVo.getHospitalNumber()) {
            wrap.eq(BPgRecord::getHospitalNumber, pgRecordQueryVo.getHospitalNumber());
        }
        // 添加 mappedTime 查询条件
        if (StringUtils.isNotEmpty(pgRecordQueryVo.getMappedTime())) {

            wrap.apply("DATE(mapped_time) = {0}", pgRecordQueryVo.getMappedTime());
        }


        // 添加按 created_time 降序排序
        wrap.orderByDesc(BPgRecord::getCreatedTime);
        List<BPgRecord> pgRecords = bPgRecordMapper.selectList(wrap);


        if (CollectionUtil.isEmpty(pgRecords)) {
            return null;
        }

        //获取角色对应的评估id
        // if (pgRecordQueryVo.getRoleId() != null) {
        //去掉根据角色id查询的条件 以前的角色id由于是写死的 这边暂时去掉这个查询条件
        //List<BPgpf> pgpfPOS = bPgpfService.selectByRoleId(pgRecordQueryVo.getRoleId());
//            List<BPgpf> pgpfPOS =bPgpfService.selectByWithoutRoleId();
//            List<Long> pgIds = pgpfPOS.stream().map(BPgpf::getId).collect(Collectors.toList());
//            List<BPgRecord> pgRecords1 = pgRecords.stream().filter(BPgRecord -> pgIds.contains(BPgRecord.getPgId())).collect(Collectors.toList());
//            List<BPgRecordResultVO> bPgRecordResultVOList = BeanUtil.copyToList(pgRecords1, BPgRecordResultVO.class);
        //   return bPgRecordResultVOList;
        // }

        List<BPgRecordResultVO> pgRecordVos = BeanUtil.copyToList(pgRecords, BPgRecordResultVO.class);
        return pgRecordVos;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean savePgRecordVo(PgRecordVo pgRecordVo) {
        BPgRecord BPgRecord = BeanUtil.toBean(pgRecordVo, BPgRecord.class);
        Long id = pgRecordVo.getId();
        if (id != null) {
            //修改
            BPgRecord BPgRecord1 = bPgRecordMapper.selectById(id);
            if (null != BPgRecord1) {
                BPgRecord.setIsTip(BPgRecord1.getIsTip());
            }
            this.updateById(BPgRecord);
            bPgRecordDetailMapper.deleteByPgRecordId(id);
        } else {
            //新增
            BPgRecord.setIsTip(1);
            checkPg(BPgRecord);
            bPgRecordMapper.insert(BPgRecord);
        }
        Date currentTime = new Date();
        //明细记录保存
        List<PgRecordDetailVo> recordDetailVos = pgRecordVo.getPgRecordDetailVos();
        if (CollectionUtil.isNotEmpty(recordDetailVos)) {
            List<BPgRecordDetail> BPgRecordDetails = BeanUtil.copyToList(recordDetailVos, BPgRecordDetail.class);
            BPgRecordDetails = BPgRecordDetails.stream().map(recordDetail -> {
                if (StringUtil.isEmpty(recordDetail.getDetailId())) {
                    throw new BizException("题目选项不能为空");
                }
                recordDetail.setPgRecordId(BPgRecord.getId());


                ZoneId zoneId = ZoneId.systemDefault();
                LocalDateTime localDateTime = currentTime.toInstant().atZone(zoneId).toLocalDateTime();
                recordDetail.setCreatedTime(localDateTime);
                recordDetail.setUpdatedTime(localDateTime);

                Long userId = ContextUtil.getUserId();
                recordDetail.setCreatedBy(userId);
                recordDetail.setUpdatedBy(userId);
                return recordDetail;
            }).collect(Collectors.toList());

            bPgRecordDetailMapper.insert(BPgRecordDetails);
        }


        return true;
    }

    public void checkPg(BPgRecord BPgRecord) {
        Long userId = ContextUtil.getUserId();
        if (bPgRecordMapper.checkPg(BPgRecord.getPatientIdent(), BPgRecord.getGradeTime(), userId, BPgRecord.getPgName())) {
            throw new BizException("此时间点已有该评分");
        }
    }

    @Override
    public PgRecordVo selectByHp(PgRecordQueryVo pgRecordQueryVo) {

        if (StringUtil.isEmpty(pgRecordQueryVo.getHospitalNumber()) ||
                pgRecordQueryVo.getPgId() == null) {
            throw new BizException("住院号或者评估id不能为空");
        }

        LambdaQueryWrapper<BPgRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(BPgRecord::getPgId, pgRecordQueryVo.getPgId())
                .eq(BPgRecord::getHospitalNumber, pgRecordQueryVo.getHospitalNumber())
                .orderByAsc(BPgRecord::getMappedTime).last("limit 0,1");
        BPgRecord pgRecord = bPgRecordMapper.selectOne(wrapper);
        if (null == pgRecord) {
            return null;
        }
        PgRecordVo recordVo = BeanUtil.toBean(pgRecord, PgRecordVo.class);

        List<PgRecordDetailVo> recordDetailVos = bPgRecordDetailService.selectByRecordId(pgRecord.getId());
        if (CollectionUtil.isNotEmpty(recordDetailVos)) {
            recordVo.setPgRecordDetailVos(recordDetailVos);
        }
        return recordVo;
    }

    @Override
    public PgRecordVo selectByRecordId(Long id) {
        BPgRecord pgRecord = bPgRecordMapper.selectById(id);
        if (null == pgRecord) {
            return null;
        }
        PgRecordVo recordVo = BeanUtil.toBean(pgRecord, PgRecordVo.class);
        recordVo.setPgRecordDetailVos(bPgRecordDetailService.selectByRecordId(id));
        return recordVo;
    }

    @Override
    public List<PgRecordVo> selectByRecordIds(List<Long> ids) {
        if (CollectionUtil.isEmpty(ids)) {
            return null;
        }
        List<BPgRecord> pgRecords = bPgRecordMapper.selectByIds(ids);
        if (CollectionUtil.isNotEmpty(pgRecords)) {
            List<PgRecordVo> pgRecordVos = BeanUtil.copyToList(pgRecords, PgRecordVo.class);
            Set<Long> sids = pgRecords.stream().map(BPgRecord::getId).collect(Collectors.toSet());
            List<PgRecordDetailVo> deatils = bPgRecordDetailService.selectDetailByRecordIds(sids);
            Map<Long, List<PgRecordDetailVo>> dmap = null;
            dmap = deatils.stream().collect(Collectors.groupingBy(PgRecordDetailVo::getPgRecordId));
            if (null == dmap) {
                dmap = new HashMap<>();
            }
            for (PgRecordVo pg : pgRecordVos) {
                pg.setPgRecordDetailVos(dmap.get(pg.getId()));
            }
            return pgRecordVos;
        } else {
            return null;
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(Long pgId) {
        BPgRecord yxPgRecord = bPgRecordMapper.selectById(pgId);
        if (yxPgRecord != null) {
            bPgRecordMapper.deleteById(pgId);
            bPgRecordDetailService.delete(pgId);
        }
    }

    @Override
    public PgRecordVo getFirstOfZk(String hospitalNumber) {


        //入科时间  尚未做  后续需要重新赋值
        Date rkDate = new Date();
        String datetimeStr = DateUtil.formatDateTime(rkDate);


        //查询疼痛
        LambdaQueryWrapper<BPgpf> wrapperPgpf = new LambdaQueryWrapper<>();
        wrapperPgpf.eq(BPgpf::getPgCode, ModelItemConstant.PGPF_TT);
        BPgpf pgpfPO = bPgpfMapper.selectOne(wrapperPgpf);

        LambdaQueryWrapper<BPgRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(BPgRecord::getHospitalNumber, hospitalNumber)
                .eq(BPgRecord::getPgId, pgpfPO.getId())
                .ge(BPgRecord::getGradeTime, datetimeStr)
                .orderByAsc(BPgRecord::getGradeTime)
                .last("limit 1");
        BPgRecord pgRecord = bPgRecordMapper.selectOne(wrapper);
//
        PgRecordVo recordVo = BeanUtil.toBean(pgRecord, PgRecordVo.class);
        return recordVo;
    }

    @Override
    public List<PgRecordOutVO> queryOnryRecord(PgRecordInVO param) {

        return bPgRecordMapper.queryOnryRecord(param);
    }

    @Override
    public List<BPgRecord> getPgRecodOfTengTong(String hospitalNumber, String startTime, String endTime, String itemCode) {
        return bPgRecordMapper.getPgRecodOfTengTong(hospitalNumber, startTime, endTime, itemCode);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveList(List<PgRecordVo> pgRecordVos, Long recordTime, String operator, String account, String patientIdent, Set<Long> pgpfs) {
        List<BPgRecord> olds = bPgRecordMapper.selectByTimeAndUserAndPgid(patientIdent, recordTime, pgpfs, operator);
        bPgRecordMapper.deleteByTimeAndUserAndPgid(patientIdent, recordTime, pgpfs, operator);
        if (CollectionUtil.isNotEmpty(olds)) {
            List<Long> pgids = olds.stream().map(BPgRecord::getId).collect(Collectors.toList());
            bPgRecordDetailMapper.deleteByPgRecordIds(pgids);
        }
        if (CollectionUtil.isEmpty(pgRecordVos)) {
            return false;
        }
        Map<Long, BPgRecord> addmap = new HashMap<>();
        Map<Long, PgRecordVo> addvosMap = new HashMap<>();
        List<BPgRecordDetail> updataDetail = new ArrayList<>();
        Long num = 0L;
        for (PgRecordVo itemvo : pgRecordVos) {
            num++;
            BPgRecord item = ConvertUtil.convert(itemvo, BPgRecord.class);
            item.setId(null);
            item.setUpdatedTime(PDateUtils.getDateTimeOfTimestamp(recordTime));
            item.setCreatedTime(PDateUtils.getDateTimeOfTimestamp(recordTime));
            item.setGradeTime(PDateUtils.getDateTimeOfTimestamp(recordTime));
            item.setMappedTime(PDateUtils.getDateTimeOfTimestamp(recordTime));
            addmap.put(num, item);
            addvosMap.put(num, itemvo);
        }
        //新增处理
        //新增主表
        if (CollectionUtil.isNotEmpty(addmap.values())) {
            bPgRecordMapper.insert(addmap.values());
        }
        for (Map.Entry<Long, BPgRecord> item : addmap.entrySet()) {
            PgRecordVo itemvo = addvosMap.get(item.getKey());
            if (CollectionUtil.isNotEmpty(itemvo.getPgRecordDetailVos())) {
                List<BPgRecordDetail> yxPgRecordDetails = ConvertUtil.convertList(itemvo.getPgRecordDetailVos(), BPgRecordDetail.class);
                yxPgRecordDetails = yxPgRecordDetails.stream().map(recordDetail -> {
                    if (StringUtil.isEmpty(recordDetail.getDetailId())) {
                        throw new BizException("题目选项不能为空");
                    }
                    recordDetail.setId(null);
                    recordDetail.setCreatedTime(item.getValue().getGradeTime());
                    recordDetail.setUpdatedTime(item.getValue().getGradeTime());
                    recordDetail.setCreatedBy(ContextUtil.getUserId());
                    recordDetail.setUpdatedBy(ContextUtil.getUserId());
                    recordDetail.setPgRecordId(item.getValue().getId());
                    return recordDetail;
                }).collect(Collectors.toList());
                updataDetail.addAll(yxPgRecordDetails);
            }
        }
        //新增所有明细
        if (CollectionUtil.isNotEmpty(updataDetail)) {
            bPgRecordDetailMapper.insert(updataDetail);
        }
        return true;
    }

    @Override
    public Map<Long, PgRecordVo> selectLatestByParams(String patientIdent, String hospitalNumber, Set<Long> pgid, Long recordTime, Long rkTime) {
        Map<Long, PgRecordVo> map = new HashMap<>();
        if (CollectionUtil.isEmpty(pgid)) {
            return map;
        }
        for (Long id : pgid) {
            List<BPgRecord> pgRecords = bPgRecordMapper.selectLatestByParams(patientIdent, hospitalNumber, id, recordTime, rkTime);
            if (CollectionUtil.isNotEmpty(pgRecords)) {
                map.put(pgRecords.get(0).getPgId(), ConvertUtil.convert(pgRecords.get(0), PgRecordVo.class));
            }
        }
        return map;
    }


    @Override
    public List<PgRecordVo> getDiseaseOverviewPgRecord(String hospitalNumber, Long rkTime, Long ckTime) {
        Date rk = null;
        Date ck = null;
        if (null != rkTime) {
            rk = new Date(rkTime);
        }
        if (null != ckTime) {
            ck = new Date(ckTime);
        }
        List<PgRecordVo> list = bPgRecordMapper.getDiseaseOverviewPgRecord(hospitalNumber, rk, ck);
        return list;
    }

    @Override
    public int countOfPainCalmPatient(String startTime, String endTime, String pgName) {
        LambdaQueryWrapper<BPgRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(BPgRecord::getPatientIdent)
                .eq(BPgRecord::getPgName, pgName)
                .between(BPgRecord::getGradeTime, startTime, endTime)
                .groupBy(BPgRecord::getPatientIdent);

        // Step 2: 获取符合条件的分组后的记录列表
        List<BPgRecord> resultList = bPgRecordMapper.selectList(wrapper);

        // Step 3: 统计分组后的记录数量
        int count = resultList.size();

        return count;
    }

    @Override
    public IPage<BPgRecordResultVO> pageOfPgRecord(QcQueryPageVO qcQueryPageVO,String pgName) {
        Page<BPgRecord> pages = new Page<>(qcQueryPageVO.getPage(), qcQueryPageVO.getSize());
//
//        QueryWrapper<BPgRecord> queryWrapper = new QueryWrapper<>();
//        queryWrapper.eq("pg_name", pgName);
//        if (StringUtils.isNotEmpty(qcQueryPageVO.getStartTime())) {
//            queryWrapper.ge("grade_time", qcQueryPageVO.getStartTime());
//        }
//        if (StringUtils.isNotEmpty(qcQueryPageVO.getEndTime())) {
//            queryWrapper.le("grade_time", qcQueryPageVO.getEndTime());
//        }
//        //部门筛选条件 等his对接后再做
//        if (StringUtils.isNotEmpty(qcQueryPageVO.getDepartmentType())) {
//
//        }
//
//        queryWrapper.orderByDesc("created_time");
//
//
//        page = bPgRecordMapper.selectPage(page, queryWrapper);
        IPage  page=bPgRecordMapper.selectPgRecordWithPatientName(pages,pgName,qcQueryPageVO.getStartTime(),qcQueryPageVO.getEndTime());
        // 简化转换
        IPage<BPgRecordResultVO> resultPage = page.convert(record -> {

//            BeanUtils.copyProperties(record, resultVO);  // 自动复制属性
            BPgRecordResultVO resultVO = BeanUtil.toBean(record, BPgRecordResultVO.class);
            return resultVO;
        });
        return resultPage;
    }

    @Override
    public List<StatisticsByMonth> painnCalmStatisticsOfSixMonth(String startTime,String pgName) {
        return bPgRecordMapper.painStatisticsOfSixMonth(startTime,pgName);
    }

}


